package com.haredot.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.haredot.dto.*;
import com.haredot.entity.Role;
import com.haredot.entity.User;
import com.haredot.exception.ServiceAccessException;
import com.haredot.mapper.RoleMapper;
import com.haredot.mapper.UserMapper;
import com.haredot.service.UserService;
import com.haredot.vo.PageVo;
import com.haredot.vo.R;
import com.haredot.vo.UserVo;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
@Transactional(rollbackFor = Exception.class)
public class UserServiceImpl implements UserDetailsService, UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private PasswordEncoder passwordEncoder ;

    @Override
    public UserDetails loadUserByUsername(String username) {
        // 根据用户名，查询对应的用户信息
        User user = userMapper.findByUsername(username);

        if (user == null) throw new UsernameNotFoundException("用户名或密码不正确");

        // del 标记 是否是超级管理员
        if (user.getDel() == null || user.getDel() == false) {
            // 根据用户名、查询对应的权限信息
            List<PermissionGrantedAuthority> authoritiesByUsername = userMapper.findAuthoritiesByUsername(username);
            user.setAuthorities(authoritiesByUsername);
        } else {
            // 如果是超级管理员，查询系统中所有的资源。
            List<PermissionGrantedAuthority> authorities = userMapper.findAllAuthorities();
            user.setAuthorities(authorities);
        }

        return user;
    }

    @Override
    public R<?> queryOrgAndPositionOrUserData(Long userId) {
        // 查询 组织机构信息 和 用户的绑定关系
        List<BindOrganizationUserDto> organizations = userMapper.findOrganizationRefUserId(userId);
        // 查询 职务信息 和用户的绑定关系
        List<BindPositionUserDto> positions = userMapper.findPositionRefUserId(userId);
        // 如果 用户不为空， 则查询 用户的 基本信息
        if (userId != null) {
            User user = userMapper.findById(userId);
            return R.ok().data(Map.of("organizations", organizations, "positions", positions, "user", user));
        }
        return R.ok().data(Map.of("organizations", organizations, "positions", positions));
    }

    @Override
    public R<?> saveUser(UserVo userVo) {
        // 查询用户名是否被注册
        User byUsername = userMapper.findByUsername(userVo.getUsername());

        if (byUsername != null) return R.fail(R.StatusCode.BAD).data(Map.of("username", "用户名已被注册"));

        // 获取密码，并进行加密
        if (userVo.getPassword() != null && !"".equals(userVo.getPassword())) {
            userVo.setPassword(passwordEncoder.encode(userVo.getPassword()));
        }
        // 插入用户信息
        int len = userMapper.insert(userVo);
        // 插入 用户组织机构 信息
        len = userMapper.batchSaveOrganizationAndUser(userVo.getId(), userVo.getOrgs());

        if (!userVo.getPositions().isEmpty()) {
            //插入 用户职务信息
            len = userMapper.batchSavePositionAndUser(userVo.getId(), userVo.getPositions());
        }

        // 查询 是否有默认角色，如果有，将默认角色 和当前用户进行绑定
        List<Role> roles = roleMapper.findDefaultRoles();

        if (!roles.isEmpty()) {
            // 批量插入用户和角色的关系
            roleMapper.batchSaveRoleAndUser(userVo.getId(), roles);
        }

        return R.ok().build();
    }

    @Override
    public R<?> updateUser(UserVo userVo) {

        if (userVo.getPassword() != null && !"".equals(userVo.getPassword())) {
            userVo.setPassword(passwordEncoder.encode(userVo.getPassword()));
        }

        // 查询用户名是否被注册
        User byUsername = userMapper.findByUsername(userVo.getUsername());

        if (byUsername != null && !Objects.equals(userVo.getId(), byUsername.getId())){
            return R.fail(R.StatusCode.BAD).data(Map.of("username", "用户名已被注册"));
        }

        // 更新用户信息
        int len = userMapper.update(userVo);
        // 删除组织机构和用户的关系
        userMapper.removeOrganizationByUserId(userVo.getId());
        // 插入 用户组织机构 信息
        len = userMapper.batchSaveOrganizationAndUser(userVo.getId(), userVo.getOrgs());

        userMapper.removePositionByUserId(userVo.getId());

        if (!userVo.getPositions().isEmpty()) {
            //插入 用户职务信息
            len = userMapper.batchSavePositionAndUser(userVo.getId(), userVo.getPositions());
        }

        return R.ok().build();
    }

    @Override
    public R<PageVo> queryUsersByPage(PageVo pageVo, Map<String, Object> searchParams) {
        PageInfo<UserAdminDTO> info = PageHelper.startPage(pageVo)
                .doSelectPageInfo(() -> userMapper.findUsersByCondition(searchParams));

        pageVo.setTotal(info.getTotal()).setList(info.getList());

        return R.<PageVo>ok().data(pageVo);
    }

    @Override
    public R<?> removeUser(Long userId) {

        int len = userMapper.deleteById(userId);

        if (len != 1) throw new ServiceAccessException("注销失败、期待删除1条、实际删除" + len + "条");

        return R.ok().build();
    }

    @Override
    public R<BindUserRoleDto> queryRolesRefUser(Long userId) {

        List<BindUserRoleDto> list = userMapper.findRolesRefUserId(userId);

        return R.<BindUserRoleDto>ok().data(list);
    }

    @Override
    public R<?> bindRolesRefUser(Long userId, List<Long> roles) {
        // 先解除绑定
        int len = userMapper.removeRoleAndUserByUserId(userId);

        if (!roles.isEmpty()) {
            userMapper.batchSaveRoleAndUser(userId, roles);
        }
        return R.ok().build();
    }
}
